<?php

declare(strict_types=1);

namespace app\admin\logic\order;

use think\facade\Db;
use app\common\ConstVar;
use app\common\model\order\ShipOrder;

class ShipOrderLogic
{
    /**
     * 获取订单状态统计数量
     * @return array 包含各状态订单数量的数组
     */
    public static function getNoticeCounts()
    {
        $counts = [];
        // 待支付订单数量
        $counts['unpaid'] = ShipOrder::where('status', 1)->count();
        // 已支付订单数量
        $counts['paid'] = ShipOrder::where('status', 2)->count();
        // 已取消订单数量
        $counts['cancelled'] = ShipOrder::where('status', 5)->count();
        // 申请退款订单数量
        $counts['refunding'] = ShipOrder::where('status', 3)->count();
        // 已退款订单数量
        $counts['refunded'] = ShipOrder::where('status', 4)->count();
        // 总订单数量
        $counts['total'] = ShipOrder::count();
        return $counts;
    }

    /**
     * 构建订单查询条件
     * @param array $param 请求参数
     * @return array 构建好的查询条件
     */
    public static function buildOrderQueryWhere(array $param): array
    {
        $where = [];

        // 联系人姓名筛选
        if (!empty($param['contact_name'])) {
            $where[] = ['ship_order.contact_name', 'like', '%' . $param['contact_name'] . '%'];
        }

        // 订单号筛选
        if (!empty($param['api_order_no'])) {
            $where[] = ['ship_order.api_order_no|order.order_sn', 'like', '%' . $param['api_order_no'] . '%'];
        }

        // 联系电话筛选
        if (!empty($param['booking_tel'])) {
            $where[] = ['ship_order.booking_tel', '=', $param['booking_tel']];
        }

        // 身份证号筛选
        if (!empty($param['idcard'])) {
            $where[] = ['ship_order.contact_list', 'like', '%' . $param['idcard'] . '%'];
        }

        // 用户ID筛选
        if (!empty($param['user_id'])) {
            $where[] = ['u.user_id', '=', $param['user_id']];
        }

        // 订单状态筛选
        if (isset($param['status']) && intval($param['status']) > 0) {
            $where[] = ['ship_order.status', '=', (int)$param['status']];
        }

        // 开始时间筛选
        if (!empty($param['start_time'])) {
            $where[] = ['ship_order.create_time', '>=', (int)strtotime($param['start_time'])];
        }

        // 结束时间筛选
        if (!empty($param['end_time'])) {
            $where[] = ['ship_order.create_time', '<=', (int)strtotime($param['end_time'])];
        }

        // 航程日期筛选
        if (isset($param['voyage_date']) && !empty($param['voyage_date'])) {
            $voyageDate = explode(' ', $param['voyage_date']);
            $rs = Db::name('change_voyage')->where('code', 10001)->where('body_arr', 'like', '%' . $voyageDate[0] . '%')->field(['ship_order_id'])->select();
            if ($rs) {
                $shipOrderIds = array_column($rs, 'ship_order_id');
                $where[] = ['id', 'in', $shipOrderIds];
            } else {
                $where[] = ['id', '=', 0];
            }
        }

        // 套餐类型筛选
        if (isset($param['package']) && intval($param['package']) > -1) {
            $where[] = ['package', '=', $param['package']];
        }

        return $where;
    }

    /**
     * 获取船舶订单数据列表
     * @param array $param 请求参数
     * @return array 包含分页数据和格式化后订单列表的数组
     */
    public static function getShipOrderList(array $param): array
    {
        $db = ShipOrder::alias('ship_order')->join('users u', 'ship_order.user_id=u.user_id');
        $where = self::buildOrderQueryWhere($param);

        // 根据订单状态设置排序方式
        $status = isset($param['status']) ? intval($param['status']) : 0;
        switch ($status) {
            case 4:     // 申请退款
            case 6:     // 待退款
                $db->order('ship_order.apply_refund_time desc');
                break;
            default:
                $db->order('ship_order.id desc');
                break;
        }

        // 获取分页数据
        $data = $db->where($where)->paginate((int)$param['limit'] ?? 10);
        $items = $data->items();

        // 处理订单数据格式化
        if (!empty($items)) {
            $orderIds = array_column($items, 'id');
            $childrenData = self::getChildrenData($orderIds);

            foreach ($items as &$item) {
                $item = self::formatOrderItem($item, $childrenData);
            }
        }

        return [
            'paginator' => $data,
            'list' => $items
        ];
    }

    /**
     * 获取订单详情并处理数据
     * @param array $param 请求参数
     * @return array 处理后的订单数据
     */
    public static function getShipOrderDetail(array $param): array
    {
        $shiporder = ShipOrder::where('id', $param['id'])->find();
        if (!$shiporder) {
            return [];
        }
        $shiporder = $shiporder->toArray();

        // 解析JSON字段
        $shiporder = self::parseOrderJsonFields($shiporder);
        // 处理票务URL
        $shiporder['ticket_url'] = self::processTicketUrl($shiporder);
        // 处理退款时间格式
        $shiporder['apply_refund_time'] = $shiporder['apply_refund_time'] > 0 ? date('Y-m-d H:i:s', $shiporder['apply_refund_time']) : '';
        // 处理退款通知信息
        $shiporder = self::processRefundNotify($shiporder);
        // 获取改签记录
        $changeVoyages = self::getChangeVoyages($param['id']);
        // 获取携带小童信息
        $takeChildren = self::getTakeChildrenInfo($param['id']);
        // 获取退款信息
        $refundInfo = self::getRefundInfo($param['id'], $shiporder['contact_list']);
        // 处理订单状态
        $shiporder['status_text'] = ConstVar::$OrderStatus[$shiporder['status']] ?? '未知状态';

        return [
            'shiporder' => $shiporder,
            'changeVoyages' => $changeVoyages,
            'take_children' => $takeChildren,
            'refundInfo' => $refundInfo
        ];
    }

    /**
     * 解析订单JSON字段
     * @param array $shiporder 订单数据
     * @return array 解析后的订单数据
     */
    private static function parseOrderJsonFields(array $shiporder): array
    {
        $jsonFields = ['contact_list', 'chooseSeat', 'chooseFlight', 'shipline', 'response'];
        foreach ($jsonFields as $field) {
            $shiporder[$field] = !empty($shiporder[$field]) ? json_decode($shiporder[$field], true) : [];
        }
        $shiporder['tc_notify'] = !empty($shiporder['tc_notify']) ? json_decode($shiporder['tc_notify'], true) : [];
        return $shiporder;
    }

    /**
     * 处理票务URL
     * @param array $shiporder 订单数据
     * @return string 处理后的URL
     */
    private static function processTicketUrl(array $shiporder): string
    {
        if (isset($shiporder['tc_notify']['ShipTripSchedule']) && $shiporder['tc_notify']['ShipTripSchedule']) {
            return 'https://' . str_replace('https://', '', $shiporder['tc_notify']['ShipTripSchedule']);
        }
        return '';
    }

    /**
     * 处理退款通知信息
     * @param array $shiporder 订单数据
     * @return array 处理后的订单数据
     */
    private static function processRefundNotify(array $shiporder): array
    {
        $tcRefundNotify = !empty($shiporder['tc_refund_notify']) ? json_decode($shiporder['tc_refund_notify'], true) : [];
        if (isset($tcRefundNotify['Result'])) {
            $shiporder['tc_refund_Result'] = $tcRefundNotify['Result'] ? '成功' : '失败';
            $shiporder['tc_ServiceCharge'] = $tcRefundNotify['Result'] ? ($tcRefundNotify['ServiceCharge'] ?? '') : 0;
        } else {
            $shiporder['tc_refund_Result'] = '暂无';
            $shiporder['tc_ServiceCharge'] = '暂无';
        }
        return $shiporder;
    }

    /**
     * 获取改签记录
     * @param int $orderId 订单ID
     * @return array 改签记录列表
     */
    private static function getChangeVoyages(int $orderId): array
    {
        $changeVoyages = Db::name('change_voyage')->where(['ship_order_id' => $orderId, 'code' => '10001'])->select();
        foreach ($changeVoyages as &$item) {
            $item['body_arr'] = !empty($item['body_arr']) ? json_decode($item['body_arr'], true) : [];
        }
        return $changeVoyages;
    }

    /**
     * 获取携带小童信息
     * @param int $orderId 订单ID
     * @return array 携带小童列表
     */
    private static function getTakeChildrenInfo(int $orderId): array
    {
        $shipOrder = ShipOrder::find($orderId);
        return $shipOrder ? $shipOrder->takeChildren()->select()->toArray() : [];
    }

    /**
     * 获取退款信息
     * @param int $orderId 订单ID
     * @param array $contactList 联系人列表
     * @return array 退款信息列表
     */
    private static function getRefundInfo(int $orderId, array $contactList): array
    {
        $shipOrder = ShipOrder::find($orderId);
        $refundInfo = $shipOrder ? $shipOrder->partialRefundList()->select()->toArray() : [];
        foreach ($refundInfo as &$item) {
            $item['refund_list'] = !empty($item['refund_list']) ? json_decode($item['refund_list'], true) : [];
            foreach ($item['refund_list'] as &$val) {
                foreach ($contactList as $v) {
                    if ($v['id_num'] == $val['CardId']) {
                        $val['username'] = $v['username'];
                        $val['TicketPrice'] = $v['TicketPrice'];
                    }
                }
            }
        }
        return $refundInfo;
    }

    /**
     * 获取订单中的儿童信息
     * @param array $orderIds 订单ID数组
     * @return array 订单儿童信息数组
     */
    private static function getChildrenData(array $orderIds): array
    {
        if (empty($orderIds)) {
            return [];
        }

        $shipOrders = ShipOrder::whereIn('id', $orderIds)
            ->withCount('takeChildren')
            ->select();

        $childrenData = [];
        foreach ($shipOrders as $order) {
            $childrenData[] = [
                'ship_order_id' => $order->id,
                'child_count' => $order->take_children_count
            ];
        }

        $result = [];
        foreach ($childrenData as $item) {
            $result[$item['ship_order_id']] = $item['child_count'] > 0;
        }

        return $result;
    }

    /**
     * 格式化订单项目数据
     * @param array $item 单个订单数据
     * @param array $childrenData 儿童信息数据
     * @return array 格式化后的订单数据
     */
    private static function formatOrderItem(array $item, array $childrenData): array
    {
        // 基本状态文本转换
        $item['status_text'] = ConstVar::$OrderStatus[$item['status']] ?? '未知状态';
        $item['is_pay_text'] = ConstVar::$YesOrNo[$item['is_pay']] ?? '未知';
        $item['pay_type_name'] = $item['pay_type'] == 1 ? '微信支付' : '支付宝支付';

        // JSON字段解析
        $item['contact_list'] = json_decode($item['contact_list'], true) ?? [];
        $item['chooseSeat'] = json_decode($item['chooseSeat'], true) ?? [];
        $item['chooseFlight'] = json_decode($item['chooseFlight'], true) ?? [];
        $item['shipline'] = json_decode($item['shipline'], true) ?? [];
        $item['tc_notify'] = json_decode($item['tc_notify'], true) ?? [];

        // 航线文本
        $item['line_text'] = isset($item['shipline']['FromCityName'], $item['shipline']['ToCityName']) ?
            $item['shipline']['FromCityName'] . '-->' . $item['shipline']['ToCityName'] : '未知航线';

        // 时间格式化
        $item['pay_time'] = $item['pay_time'] ? date('Y-m-d H:i:s', $item['pay_time']) : '暂无';
        $item['refund_time'] = $item['refund_time'] ? date('Y-m-d H:i:s', $item['refund_time']) : '暂无';
        $item['go_time'] = $item['chooseFlight']['DepartureDate'] ?? '';

        // 票务链接处理
        $item['ticket_url'] = '';
        if (isset($item['tc_notify']['ShipTripSchedule']) && $item['tc_notify']['ShipTripSchedule']) {
            $item['ticket_url'] = 'https://' . str_replace('https://', '', $item['tc_notify']['ShipTripSchedule']);
        }

        // 会员等级名称
        $item['vip_level_text'] = Db::name('user_level')->where('id', $item['vip_level'])->value('name') ?? '普通会员';

        // 儿童信息标记
        $item['has_children'] = $childrenData[$item['shiporder_id']] ?? false;

        return $item;
    }
}
